import json

import IPy
import  traceback
from flask import current_app, request
from tools.basic_tools import Tools
from app.common.zstack_manager import ZStackManager
from app.models import rangeModel, switchModel, RangeVm, Image
from app.common.range_manager import  RangeManager
from tools import db
from flask_restx import abort
from app.api.v1.webhook.operate_config import OPERATE_TYPE_DELETE_FUNCTION, DELETE_OPERATE_TYPE, container_status_map

class WebHookManager(ZStackManager):
    def __init__(self):
        super(WebHookManager, self).__init__()
        
    
    def create_image(self, image_name, image_url, image_id, image_type, os_type, **kwargs):
        """上传镜像"""
        
        requests_data = {
            "name": image_name, 
            "file_url": image_url, 
            "resource_uuid": image_id,
            "os_type": os_type,
            "image_type": image_type,
            "backup_storage_uuids": [current_app.config["ZSTACK_CLOUD"]["backup_storage_uuid"]],
            "action": f"上传镜像: {image_name}",
            "user_only":  kwargs.get("user_only")
        }
        return super().create_image(**requests_data)
  
    def del_image_destroy(self, image_uuid, del_model="Permissive", **kwargs):
        """删除镜像"""
        requests_data = {
            "image_uuid": image_uuid,
            "del_model": del_model,
            "action": f"删除镜像: {image_uuid}",
            "user_only":  kwargs.get("user_only"),
            "url_param": {
                "follow_up": "del_image_expunge",
                "image_uuid": image_uuid
            }
        }
        return super().del_image_destroy(**requests_data)
            
    def del_image_expunge(self, image_uuid, **kwargs):
        """彻底删除镜像"""
        request_data = {
            "image_uuid": image_uuid,
            "action": f"彻底删除镜像: {image_uuid}",
            "user_only": kwargs.get("user_only"),
            "url_param": {
                "follow_up": "del_image_database",
                "image_uuid": image_uuid
            }
        }
        return super().del_image_expunge(**request_data)
    
    def create_l2_vxlan_network_pool(self, name, vxlan_pool_id, start_vni, end_vni, **kwargs):
        """创建vxlan-pool
        """
        zone_uuid = current_app.config["ZSTACK_CLOUD"]["zone_uuid"]
        cluster_uuid = current_app.config["ZSTACK_CLOUD"]["cluster_uuid"]
        requests_data = {
            "zone_uuid": zone_uuid,
            "cluster_uuid": cluster_uuid,
            "name": name,
            "resource_uuid": vxlan_pool_id,
            "action": "创建vxlan-pool池",
            "user_only":  kwargs.get("user_only"),
            "url_param": {
                "start_vni": start_vni,
                "end_vni": end_vni,
                "follow_up": "create_vni_range"
            }
        }
        return super().create_l2_vxlan_network_pool(**requests_data)
        
    def create_vni_range(self, uuid, start_vni, end_vni, name="CreateVniRange", resource_uuid=Tools.get_uuid4_no_line(), **kwargs):
        """创建vni

        Args:
            uuid (_type_): vxlan_pool 的 uuid
        """
        requests_data = {
            "name": name,
            "l2_network_uuid": uuid,
            "start_vni": start_vni,
            "end_vni": end_vni,
            "resource_uuid": resource_uuid,
            "action": "创建VNI",
            "user_only": kwargs.get("user_only"),
            "url_param": {
                "follow_up": "attach_l2_network_to_cluster",
                "vxlan_pool_id": uuid
                }
        }
        return super().create_vni_range(**requests_data)
        
    def attach_l2_network_to_cluster(self, vxlan_pool_id, **kwargs):
        """添加集群"""
        request_data = {
            "l2_network_uuid": vxlan_pool_id,
            "action": "挂载集群",
            "cidr": current_app.config["ZSTACK_CLOUD"]["cidr"],
            "cluster_uuid": current_app.config["ZSTACK_CLOUD"]["cluster_uuid"],
            "user_only": kwargs.get("user_only"),
        }
        return super().attach_l2_network_to_cluster(**request_data)
        
    # def create_l2_vxlan_network(self, vxlan_pool_id, network_id, name, **kwargs):
    #     """创建vxlan二层网络"""
    #     request_data = {
    #         "pool_uuid": vxlan_pool_id,
    #         "name": name,
    #         "zone_uuid": current_app.config["ZSTACK_CLOUD"]["zone_uuid"],
    #         "resource_uuid": network_id,
    #         "user_only": kwargs.get("user_only"),
    #         "action": "创建二层网络",
    #         "push_message": kwargs.get("push_message", 1)
    #     }
    #     return super().create_l2_vxlan_network(**request_data)
        
    # def create_l3_network(self, network_id, subnet_id, cidr, switch_name="交换机", **kwargs):
    #     """创建三层网络"""
    #     request_data = {
    #         "l2_network_uuid": network_id, 
    #         "name": switch_name, 
    #         "resource_uuid": subnet_id,
    #         "action": f"创建交换机:{subnet_id}",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "attach_network_service_to_l3Network",
    #             "cidr": cidr,
    #             "subnet_id": subnet_id
    #         }
    #     }
    #     return super().create_l3_network(**request_data)
    
    # def attach_network_service_to_l3Network(self, uuid, network_service=None, **kwargs):
    #     """将三层网络加入到网络服务"""
    #     request_data = {
    #         "l3_network_uuid": uuid,
    #         "action": "通过网络cidr添加ip地址范围",
    #         "user_only": kwargs.get("user_only"),
    #     }
    #     if not network_service:
    #         request_data["network_service"] = current_app.config["ZSTACK_CLOUD"]["network_service"]
    #         request_data["url_param"] = {
    #                 "follow_up": "create_l3_network_ip_ranges",
    #                 "cidr": kwargs["cidr"],
    #                 "subnet_id": uuid
    #             }
    #     else:
    #         request_data["network_service"] = network_service
        
    #     return super().attach_network_service_to_l3Network(**request_data)
        
    # def create_l3_network_ip_ranges(self, uuid, cidr, **kwargs):
    #     """添加三层网络cidr"""
    #     request_data = {
    #         "l3_network_uuid": uuid, 
    #         "network_cidr": cidr, 
    #         "action": "通过网络cidr添加ip地址范围",
    #         "user_only": kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "add_dns_to_l3_network",
    #             "subnet_id": uuid
    #         }
    #     }
    #     return super().create_l3_network_ip_ranges(**request_data)
        
    # def add_dns_to_l3_network(self, l3NetworkUuid, dns=None, **kwargs):
    #     """三层网络添加dns"""
    #     if not dns:
    #         dns = current_app.config["ZSTACK_CLOUD"]["dns"]
    #     requests_data = {
    #         "l3_network_id": l3NetworkUuid,
    #         "dns": dns,
    #         "user_only": kwargs.get("user_only"),
    #         "action": "三层网络添加dns"
    #     }
    #     return super().add_dns_to_l3_network(**requests_data)
    
    # def create_vpc_router(self, name, router_offering_uuid, resource_uuid, **kwargs):
    #     """创建vpc路由器"""
    #     requests_data = {
    #         "name": name, 
    #         "router_offering_uuid": router_offering_uuid, 
    #         "resource_uuid": resource_uuid,
    #         "user_only":  kwargs.get("user_only"),
    #         "action": f"创建路由器: {resource_uuid}",
    #         "url_param": {
    #             "op_route":  resource_uuid
    #         }
    #     }
    #     # 判断是否存在url_param
    #     if kwargs.get("url_param"):
    #         requests_data["url_param"].update(kwargs["url_param"])
    #     return super().create_vpc_router(**requests_data)
    
    # def create_vm(self, name, instance_offering_uuid, image_uuid, l3Network_uuids, dataDisk_offering_uuids, resource_uuid, ip, port_id, **kwargs):
    #     """创建虚拟机"""
    #     requests_data = {
    #         "name": name, 
    #         "instance_offering_uuid": instance_offering_uuid, 
    #         "image_uuid": image_uuid, 
    #         "dataDisk_offering_uuids": dataDisk_offering_uuids, 
    #         "resource_uuid": resource_uuid, 
    #         "action": f"创建虚拟机: {resource_uuid}",
    #         "l3Network_uuids":  l3Network_uuids if isinstance(l3Network_uuids, list) else [l3Network_uuids],
    #         "user_only":  kwargs.get("user_only")
    #     }
    #     if len(requests_data["l3Network_uuids"]) > 1:
    #         requests_data["default_l3_network_uuid"] = requests_data["l3Network_uuids"][0]
        
    #     if kwargs["follow_up"] == "update_vm_ip_database"  and kwargs["dst_end_points"]:
    #         # 创建并加载会话
    #         requests_data["url_param"] = {
    #             "follow_up": "update_port_mirror_session",
    #             "name": name,
    #             "port_id": port_id,
    #             "device_type": "vm",
    #             "op_vm_uuid": resource_uuid,
    #             "dst_end_point": kwargs["dst_end_points"]
    #         }

    #     elif kwargs["follow_up"] == "update_vm_ip_database":
    #         requests_data["url_param"] = {
    #             "follow_up": "update_vm_ip_database",
    #             "port_id": port_id,
    #             "device_type": "vm",
    #             "op_vm_uuid": resource_uuid
    #         }
    #     elif kwargs["follow_up"] == "create_port_mirror_session":
    #         requests_data["url_param"] = {
    #             "follow_up": "create_port_mirror_session",
    #             "name": name,
    #             "src_end_points": kwargs["src_end_points"],
    #             "port_id":  port_id
    #         }
    #     if ip:
    #         requests_data["systemTags"] = [f"staticIp::{l3Network_uuids[0] if isinstance(l3Network_uuids, list) else l3Network_uuids}::{ip}"]
    #     print(requests_data)
    #     return super().create_vm(**requests_data)

    # def del_vm_destroy(self, vm_uuid, del_model="Permissive", **kwargs):
    #     """删除云主机"""
    #     requests_data = {
    #         "vm_uuid": vm_uuid,
    #         "del_model": del_model,
    #         "action": f"删除云主机: {vm_uuid}",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "del_vm_expunge",
    #             "vm_uuid": vm_uuid
    #         }
    #     }
    #     return super().del_vm_destroy(**requests_data)
            
    # def del_vm_expunge(self, vm_uuid, **kwargs):
    #     """彻底删除云主机"""
    #     request_data = {
    #         "vm_uuid": vm_uuid,
    #         "action": f"彻底删除云主机: {vm_uuid}",
    #         "user_only": kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "del_vm_database",
    #             "vm_uuid": vm_uuid
    #         }
    #     }
    #     return super().del_vm_expunge(**request_data)
    
    # def start_vm(self, vm_uuid, **kwargs):
    #     """开启云主机"""
        
    #     request_data = {
    #         "vm_uuid": vm_uuid,
    #         "action": f"开启云主机: {vm_uuid}",
    #         "user_only":  kwargs.get("user_only")
    #     }
    #     return super().start_vm(**request_data)
    
    # def stop_vm(self, vm_uuid, **kwargs):
    #     """关闭云主机"""
        
    #     request_data = {
    #         "vm_uuid": vm_uuid,
    #         "action": f"关闭云主机: {vm_uuid}",
    #         "user_only":  kwargs.get("user_only")
    #     }
    #     return super().stop_vm(**request_data)
    
    # def attach_l3network_route(self, route_uuid, l3_network_uuid, port_id, ip, **kwargs):
    #     requests_data = {
    #         "route_uuid": route_uuid, 
    #         "l3_network_uuid": l3_network_uuid,
    #         "action": "加载vpc路由到vpc网络",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "update_vm_ip_database",
    #             
    #         }
    #     }
    #     return super().attach_l3network_route(**requests_data)
    
    # def del_l3_network(self, l3_network_uuid, delete_mode="Permissive", **kwargs):
    #     """删除vpc网络"""
    #     request_data = {
    #         "l3_network_uuid": l3_network_uuid,
    #         "action": f"删除交换机: {l3_network_uuid}",
    #         "delete_mode": delete_mode,
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "del_switch_database",
    #             "l3_network_uuid": l3_network_uuid
                
    #         }
    #     }
    #     return super().del_l3_network(**request_data)

    # def del_vm_nic(self, network_nic_uuid, **kwargs):
    #     """卸载虚拟网卡-(解绑路由)"""
    #     request_data = {
    #         "network_nic_uuid": network_nic_uuid,
    #         "action": f"卸载VPC路由器: {network_nic_uuid}",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "del_connect_router_database",
    #             "port_id": network_nic_uuid
    #         }
    #     }
    #     return super().del_vm_nic(**request_data)

    # def detach_l3_network_vm(self, vm_network_id, **kwargs):
    #     """卸载云主机的网卡"""
    #     request_data = {
    #         "vm_network_id": vm_network_id,
    #         "action": f"虚拟机卸载虚拟网卡: {vm_network_id}",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "del_connect_vm_database",
    #             "port_id": vm_network_id
    #         }
    #     }
    #     return super().detach_l3_network_vm(**request_data)

    # def del_router(self, router_uuid, **kwargs):
    #     """删除vpc路由器"""
    #     request_data = {
    #         "vm_uuid": router_uuid,
    #         "action": f"删除vpc路由器: {router_uuid}",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "del_router_database",
    #             "router_uuid": router_uuid
    #         }
    #     }
    #     return super().del_vm_destroy(**request_data)

    # def create_vip_action(self, name, l3_network_uuid, **kwargs):
    #     """创建虚拟ip"""
    #     request_data = {
    #         "name": name,
    #         "l3_network_uuid": l3_network_uuid,
    #         "action": f"创建虚拟ip: {name}",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "create_eip_action",
    #             "op_vm_uuid": kwargs["op_vm_uuid"]
    #         }
    #     }
    #     return super().create_vip_action(**request_data)
    
    # def create_eip_action(self, name, uuid, **kwargs):
    #     """创建弹性ip"""
    #     request_data = {
    #         "name": name,
    #         "vip_uuid": uuid,
    #         "action": f"创建弹性ip: {name}",
    #         "user_only": kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "update_vm_external_ip",
    #             "op_vm_uuid": kwargs["op_vm_uuid"]
    #         }
    #     }
    #     return super().create_eip_action(**request_data)
    
    def attach_eip_to_vm(self, eip_uuid, vm_uuid, **kwargs):
        """加载弹性IP到虚拟机"""
        # 获取网卡
        port_info = switchModel.Ports.query.filter_by(device_id=vm_uuid).first()
        request_data = {
            "eip_uuid": eip_uuid,
            "vm_nic_uuid": port_info.port_id,
        }
        return super().attach_eip_to_vm(**{**request_data, **kwargs})
    
    def attach_active_eip_to_vm(self, eip_uuid, vm_uuid, **kwargs):
        """加载弹性IP到虚拟机"""
        # 获取网卡
        port_info = switchModel.ActivePorts.query.filter_by(device_id=vm_uuid).first()
        request_data = {
            "eip_uuid": eip_uuid,
            "vm_nic_uuid": port_info.port_id,
        }
        return super().attach_eip_to_vm(**{**request_data, **kwargs})
    
    # def get_vm_metric(self, vm_uuid, metric_name, start_time, end_time, **kwargs):
    #     """获取监控数据"""
    #     request_data = {
    #         "vm_uuid": vm_uuid, 
    #         "metricName": metric_name, 
    #         "startTime": start_time, 
    #         "endTime": end_time,
    #         "action": "获取云主机监控数据"
    #     }
    #     return super().get_vm_metric(**request_data)
    
    # def del_l2_network(self, network_id, **kwargs):
    #     """删除基础网络"""
    #     request_data = {
    #         "network_id": network_id,
    #         "action": f"删除场景: {kwargs['range_uuid']}",
    #         "user_only":  kwargs.get("user_only"),
    #         "url_param": {
    #             "follow_up": "del_range_database",
    #             "range_uuid": kwargs["range_uuid"]
    #         }
    #     }
    #     return super().del_l2_network(**request_data)
        
    def create_port_mirror_session(self, name, src_end_points, port_id, **kwargs):
        """创建端口镜像会话"""
        # 更新port_id
        #
        try:
            port_obj = switchModel.Ports.query.filter_by(port_id=port_id)
            # 获取默认网卡, deviceId = 0
            default_vm_nic = "" 
            default_vm_ip = ""
            vm_nics = kwargs["vmNics"]
            for vm in vm_nics:
                device_id = vm["deviceId"]
                if device_id == 0:
                    default_vm_nic = vm["uuid"]
                    default_vm_ip = vm["ip"]
                else:
                    dst_end_point = vm["uuid"]
            port_obj.update({"ip": default_vm_ip, "port_id": default_vm_nic})
            rangeModel.RangeVm.query.filter_by(op_vm_uuid=kwargs["uuid"]).update({"v4_fixed_ip": default_vm_ip})
            db.session.commit()
        except Exception:
            print(traceback.print_exc())
            db.session.rollback()
        
        for src_end in src_end_points:
            resource_uuid = Tools.get_uuid4_no_line()
            request_data = {
                "port_mirror_uuid": current_app.config["ZSTACK_CLOUD"]["port_mirror_uuid"],
                "name": name,
                "src_end_point": src_end,
                "dst_end_point": dst_end_point,
                "resource_uuid": resource_uuid
            }
            super().create_port_mirror_session(**{**request_data, **kwargs})


    def create_all_port_mirror_session(self, src_end_points_vm, nids_vm_uuid, **kwargs):
        # 一键开启的端口镜像

        port_info = switchModel.Ports.query.filter(switchModel.Ports.device_id.in_(src_end_points_vm)).all()
        src_end_points = [port.port_id  for port in port_info]
        range_vm = RangeVm.query.filter_by(vm_uuid=nids_vm_uuid).first()
        op_vm_uuid = range_vm.op_vm_uuid
        result = self.get_vm_details(op_vm_uuid)
        for vm_nic in result[0]["vmNics"]:
            if vm_nic["deviceId"] == 1:
                dst_end_point = vm_nic["uuid"]
        
        for src_end in src_end_points:
            resource_uuid = Tools.get_uuid4_no_line()
            request_data = {
                "port_mirror_uuid": current_app.config["ZSTACK_CLOUD"]["port_mirror_uuid"],
                "name": resource_uuid,
                "src_end_point": src_end,
                "dst_end_point": dst_end_point,
                "resource_uuid": resource_uuid
            }
            super().create_port_mirror_session(**{**request_data, **kwargs})

    def create_all_active_port_mirror_session(self, src_end_points_vm, nids_vm_uuid, **kwargs):
        # 一键开启的端口镜像
        port_info = switchModel.ActivePorts.query.filter(switchModel.ActivePorts.device_id.in_(src_end_points_vm)).all()
        src_end_points = [port.port_id for port in port_info]
        # range_vm = RangeVm.query.filter_by(vm_uuid=nids_vm_uuid).first()
        range_vm = rangeModel.ActiveRangeVm.query.filter_by(new_vm_uuid=nids_vm_uuid).first()
        op_vm_uuid = range_vm.op_vm_uuid
        result = self.get_vm_details(op_vm_uuid)
        for vm_nic in result[0]["vmNics"]:
            if vm_nic["deviceId"] == 1:
                dst_end_point = vm_nic["uuid"]
        for src_end in src_end_points:
            resource_uuid = Tools.get_uuid4_no_line()
            request_data = {
                "port_mirror_uuid": current_app.config["ZSTACK_CLOUD"]["port_mirror_uuid"],
                "name": resource_uuid,
                "src_end_point": src_end,
                "dst_end_point": dst_end_point,
                "resource_uuid": resource_uuid
            }
            super().create_port_mirror_session(**{**request_data, **kwargs})
        

    def update_port_mirror_session(self, name, dst_end_point, **kwargs):
        """更新会话"""
        resource_uuid = Tools.get_uuid4_no_line()
        vm_nic_uuid = kwargs["vmNics"][0]["uuid"]
        request_data = {
            "port_mirror_uuid": current_app.config["ZSTACK_CLOUD"]["port_mirror_uuid"],
            "name": name,
            "src_end_point": vm_nic_uuid,
            "dst_end_point": dst_end_point,
            "resource_uuid": resource_uuid,
        }
        super().create_port_mirror_session(**{**request_data, **kwargs})
        

    def create_security_group(self, name, security_group_uuid, description, **kwargs):
        """创建安全组"""
        
        request_data = {
            "name": name, 
            "resource_uuid": security_group_uuid, 
            "description": description,
            "action": f"创建安全组: {name}",
            "user_only":  kwargs.get("user_only")
        }
        return super().create_security_group(**request_data)
    
    def del_security_group(self, security_group_uuid, **kwargs):
        """删除安全组"""
        request_data = {
            "security_group_uuid": security_group_uuid,
            "action": f"删除安全组: {security_group_uuid}",
            "user_only":  kwargs.get("user_only"),
            "url_param": {
                "follow_up": "del_security_group_database",
                "security_group_uuid": security_group_uuid
            }
        }
        return super().del_security_group(**request_data)
    
    def attach_security_group_rule(self, security_group_uuid, direction, start_port, end_port, protocol, allowed_cidr, ip_version=4, **kwargs):
        """创建安全组规则"""
        
        request_data = {
            "security_group_uuid": security_group_uuid,
            "rules": [{
               "type": direction,
               "allowed_cidr" : allowed_cidr,
               "protocol" : protocol,
               "ipVersion": ip_version
            }],
            "remote_security_group_uuid": [security_group_uuid],
            "action": f"安全组添加规则: {security_group_uuid}",
            "user_only":  kwargs.get("user_only")
        }
        if start_port == end_port  != -2:
            request_data["rules"][0].update({
                "startPort": start_port,
                "end_port" : end_port,
            })
        return super().attach_security_group_rule(**request_data)
        
    def del_security_group_rule(self, rule_id, **kwargs):
        """删除安全组规则"""
        
        request_data = {
            "rule_uuid": rule_id,
            "action": f"删除安全组规则: {rule_id}",
            "user_only":  kwargs.get("user_only")
        }
        return super().del_security_group_rule(**request_data)
    
    def attach_security_group_l3_network(self, security_group_uuid, l3_network_uuid, vm_nic_uuids, **kwargs):
        """加载安全组到l3网络"""
        
        request_data = {
            "security_group_uuid": security_group_uuid, 
            "l3_network_uuid": l3_network_uuid,
            "action": f"关联安全组: {security_group_uuid}",
            "user_only":  kwargs.get("user_only"),
            "url_param": {
                "follow_up": "attach_vm_nic_security_group",
                "vm_nic_uuids": vm_nic_uuids
            }
        }
        return super().attach_security_group_l3_network(**request_data)
    
    def attach_vm_nic_security_group(self, uuid, vm_nic_uuids, **kwargs):
        """添加虚拟机网卡到安全组"""
        request_data = {
            "security_group_uuid": uuid,
            "vm_nic_uuids": eval(vm_nic_uuids),
            "action": f"关联安全组: {uuid}-{vm_nic_uuids}",
            "user_only": kwargs.get("user_only")
        }
        return super().attach_vm_nic_security_group(**request_data)
    
    def add_stack_template(self, name, template_content, resource_uuid, range_uuid, **kwargs):
        """添加资源栈模板"""
        
        request_data = {
            "name": name, 
            "template_content": json.dumps(template_content), 
            "resource_uuid": resource_uuid,
            "action": "关联比赛场景",
            "user_only":  kwargs.get("user_only"),
            "url_param": {
                "follow_up": "add_stack_template_database",
                "range_uuid": range_uuid,
                "stack_name": name,
                "is_system": kwargs.get("is_system", 0)
            }
        }
        return super().add_stack_template(**request_data)
    
    def create_resource_stack(self, name, template_uuid, resource_uuid, range_uuid, user_id=None, follow_up="add_stack_resource_database", **kwargs):
        """创建资源栈"""
        
        request_data = {
            "name": name,
            "template_uuid": template_uuid,
            "resource_uuid": resource_uuid,
            "action": "开启环境",
            "user_only": kwargs.get("user_only"),
            "url_param": {
                "follow_up": "add_stack_resource_database",
                "stack_uuid": template_uuid,
                "user_id": user_id,
                "range_uuid": range_uuid,
            }
            if follow_up == "add_stack_resource_database"
    else {"follow_up": follow_up, "range_uuid": range_uuid},
        }
        return super().create_resource_stack(**request_data)
    
    def get_resource_from_resource_stack(self, uuid, range_uuid=None, **kwargs):
        
        request_data = {
            "resource_uuid": uuid
        }
        
        result = super().get_resource_from_resource_stack(**request_data)
        if kwargs.get("get_data", False):
            return result
        # 更新数据库
        try:
            # 更新json
            range_info = rangeModel.Range.query.join(
                    rangeModel.RangeLinkModule, rangeModel.RangeLinkModule.range_id == rangeModel.Range.id
                ).filter_by(range_uuid=range_uuid).first()
            
            topology_json = json.loads(range_info.topology_json)
            nodeList = topology_json["nodeList"]
            
            for resource in result["resources"]:
                for key, value in resource.items():
                    if key == "L2VxlanNetwork": # 二层网络
                        rangeModel.RangeLinkModule.query.filter_by(
                            range_uuid=range_uuid
                        ).update({"network_id": value["uuid"]})
                    elif key == "L3Network": # 交换机
                        cidr = value["ipRanges"][0]["networkCidr"]
                        for node in nodeList:
                            if node["type"] == "switch" and node["cidr"] == cidr:
                                node["subnet_id"] = value["uuid"],
                                node["state"] = "ACTIVE"
                        switch = switchModel.Switchs.query.filter_by(
                            range_uuid=range_uuid, cidr=cidr
                        )
                        
                        subnet_id_old = switch.first().subnet_id
                        
                        switch.update({
                            "subnet_id": value["uuid"],
                            "network_id": value["l2NetworkUuid"]
                        })
                        switchModel.Ports.query.filter_by(
                            range_uuid=range_uuid,
                            subnet_id=subnet_id_old,
                        ).update({
                            "subnet_id": value["uuid"],
                            "network_id":  value["l2NetworkUuid"]
                        })
                    elif key == "VmInstance" and not value["name"].startswith("vrouter.l3."):  # 虚拟机
                        state = value["state"]
                        port_id = value["vmNics"][0]["uuid"]
                        ip = value["vmNics"][0]["ip"]
                        name = value["name"]
                        subnet_id = value["defaultL3NetworkUuid"]                        
                        # 查询
                        port = switchModel.Ports.query.filter_by(
                            range_uuid=range_uuid, subnet_id=subnet_id, ip=ip
                        )
                        device_id = port.first().device_id
                        
                        port.update({
                            "port_id": port_id
                        })
                        rangeModel.RangeVm.query.filter_by(
                            range_uuid=range_uuid, vm_uuid=device_id
                        ).update({
                            "op_vm_uuid": value["uuid"],
                            "op_vm_name": name,
                            "subnet_id": value["defaultL3NetworkUuid"]
                        })
                        for node in nodeList:
                            if node["name"] == name:
                                node["port_id"] = port_id
                                node["port_ip"] = ip,
                                node["state"] = container_status_map.get(state, "")
                                node["vm_port_ip"] = "true"
            rangeModel.Range.query.filter_by(id=range_info.id).update({
                "topology_json": json.dumps(topology_json, ensure_ascii=False)
            })
            db.session.commit()
                                                
        except Exception:
            db.session.rollback()
            print(traceback.print_exc())
            abort(500, message="更新失败")
             
    def del_stack_template(self, stack_uuid, **kwargs):
        """删除场景模板"""
        request_data = {
            "stack_uuid": stack_uuid,
            "action": f"场景模板: {stack_uuid}",
            "user_only":  kwargs.get("user_only")
        }
        return super().del_stack_template(**request_data)
    
    def del_resource_stack(self, stack_uuid, **kwargs):
        """删除资源栈

        Args:
            stack_uuid (_type_): _description_
        """
        request_data = {
            "stack_uuid": stack_uuid,
            "action": f"场景: {stack_uuid}",
            "user_only":  kwargs.get("user_only"),
        }
        
        if kwargs.get("delete_db"):
            request_data["url_param"] = {
                "follow_up": "del_range_database",
                "range_uuid": Tools.str_to_uuid_str(stack_uuid)
            }
            
        return super().del_resource_stack(**request_data)
    
    # def create_vm_nic(self, network_uid, port_id, op_vm_uuid, ip, **kwargs):
    #     """创建虚拟网卡"""
        
    #     request_data = {
    #         "network_uid": network_uid,
    #         "resource_uuid": port_id,
    #         "user_only":  kwargs.get("user_only"),
    #         "ip": ip if ip else None,
    #         "url_param": {
    #             "follow_up": "attach_vm_nic_vm",
    #             "vm_uuid": op_vm_uuid
    #         }
    #     }
        
    #     return super().create_vm_nic(**request_data)
    
    # ============= db ================== 
    def update_all_operate_database(self, network_id, range_uuid, range_id, **kwargs):
        try:
            switchModel.Ports.query.filter_by(range_uuid=range_uuid).update({"network_id": network_id})
            rangeModel.RangeLinkModule.query.filter_by(range_uuid=range_uuid).update({"network_id": network_id})
            switchModel.Switchs.query.filter_by(range_uuid=range_uuid).update({"network_id": network_id})
            switchModel.Routes.query.filter_by(range_uuid=range_uuid).update({"state": 1})
            RangeVm.query.filter_by(range_uuid=range_uuid).update({"state": 1})
            range_obj = rangeModel.Range.query.filter_by(id=range_id)
            topology_json = range_obj.first().topology_json
            update_topology_json = Tools.update_topology_json(topology_json, all_state="ACTIVE")
            range_obj.update({"topology_json": json.dumps(update_topology_json, ensure_ascii=False)})
            db.session.commit()
        except Exception:
            db.session.rollback()
            print(traceback.print_exc())
        return
    
    
    def update_all_active_operate_database(self, range_uuid, network_id, **kwargs):
        try:
            rangeModel.ActiveRange.query.filter_by(activeRange_range_uuid=range_uuid).update({"network_id": network_id, "status": "ACTIVE"})
            db.session.commit()
        except Exception:
            db.session.rollback()
        return
    
    def update_active_vm_ip_database(self, port_id, device_type, op_vm_uuid=None, **kwargs):
        # 更新数据库ip地址
        vm_nic_uuid = ""
        ip = ""
        if device_type == "router":
            l3_network_uuid = kwargs["l3_network_uuid"]
            for vm_nic in kwargs["vmNics"]:
                if vm_nic["l3NetworkUuid"] == l3_network_uuid:
                    ip = vm_nic["ip"]
                    vm_nic_uuid = vm_nic["uuid"]
        elif device_type == "vm":
            ip = kwargs["vmNics"][0]["ip"]
            vm_nic_uuid = kwargs["vmNics"][0]["uuid"]
        elif device_type == "NIDS":
            ip = kwargs["vmNics"][-1]["ip"]
            vm_nic_uuid = kwargs["vmNics"][-1]["uuid"]
        try:
            port_obj = switchModel.ActivePorts.query.filter_by(
                port_id=port_id
            )
            port_obj.update({"ip": ip, "port_id": vm_nic_uuid})
            if op_vm_uuid:
                rangeModel.ActiveRangeVm.query.filter_by(op_vm_uuid=op_vm_uuid).update({"v4_fixed_ip": ip})
            db.session.commit()
        except Exception:
            print(traceback.print_exc())
            db.session.rollback()
        return 

    
    def update_vm_ip_database(self, port_id, device_type, op_vm_uuid=None, **kwargs):
        # 更新数据库ip地址
        vm_nic_uuid = ""
        ip = ""
        
        if device_type == "router":
            l3_network_uuid = kwargs["l3_network_uuid"]
            for vm_nic in kwargs["vmNics"]:
                if vm_nic["l3NetworkUuid"] == l3_network_uuid:
                    ip = vm_nic["ip"]
                    vm_nic_uuid = vm_nic["uuid"]
        elif device_type == "vm":
            ip = kwargs["vmNics"][0]["ip"]
            vm_nic_uuid = kwargs["vmNics"][0]["uuid"]
        elif device_type == "NIDS":
            ip = kwargs["vmNics"][-1]["ip"]
            vm_nic_uuid = kwargs["vmNics"][-1]["uuid"]
        try:
            port_obj = switchModel.Ports.query.filter_by(
                port_id=port_id
            )
            port_info = port_obj.first()
            update_dict = {"ip": ip, "port_id": vm_nic_uuid}
            if kwargs.get("network_id"):
                update_dict["network_id"] = kwargs.get("network_id")
            port_obj.update(update_dict)
            if op_vm_uuid:
                rangeModel.RangeVm.query.filter_by(op_vm_uuid=op_vm_uuid).update({"v4_fixed_ip": ip, "state": 1})
            # 更新router状态
            if device_type == "router":
                switchModel.Routes.query.filter_by(op_route=port_info.device_id).update({"state": 1})
            db.session.commit()
        except Exception:
            print(traceback.print_exc())
            db.session.rollback()
        return 

    def update_router_state(self, op_route, **kwargs):
        try:
            switchModel.Routes.query.filter_by(op_route=op_route).update({"state": 1})
            db.session.commit()
        except Exception:
            db.session.rollback()
        return

    def del_vm_database(self, vm_uuid, field="op_vm_uuid", **kwargs):
        # sourcery skip: assign-if-exp, extract-method
        """删除云主机数据库"""
        try:
            if field == "op_vm_uuid":
                vmInfo = RangeVm.query.filter_by(op_vm_uuid=vm_uuid).first()
            else:
                vmInfo = RangeVm.query.filter_by(vm_uuid=vm_uuid).first()
            if not vmInfo:
                return {"code": 0, "data": "删除成功"}
            # 清除对应数据库
            db.session.delete(vmInfo)
            
            rangInfo = rangeModel.RangeLinkModule.query.filter_by(range_uuid = vmInfo.range_uuid).first()
            # 修改虚拟机数量
            rangeModel.Range.query.filter_by(id=rangInfo.range_id).update({"vmNum": rangeModel.Range.vmNum - 1})
            switchModel.Ports.query.filter_by(
                device_id=vmInfo.vm_uuid, range_uuid=vmInfo.range_uuid
            ).update({"device_id": None, "device_owner": None})
            # TODO 如果有快照，也一并删除
            db.session.commit()
            return {"code": 0, "data": "删除成功"}
        except Exception:
            db.session.rollback()
            print(traceback.print_exc())
            abort(400, message=f"删除云主机失败: {vm_uuid}")
    
    def del_image_database(self, image_uuid, **kwargs):
        """删除镜像数据库"""
        try:
            vm_image = Image.query.filter_by(image_id=image_uuid).first()
            if  vm_image:
                db.session.delete(vm_image)
                db.session.commit()
        except Exception:
            db.session.rollback()
            print(traceback.print_exc())
            abort(400, message="删除镜像失败")
        
    def del_switch_database(self, subnet_id, **kwargs):
        # sourcery skip: extract-method
        """删除交换机"""
        try:
            switch = switchModel.Switchs.query.filter_by(subnet_id=subnet_id).first()
            if not switch:
                return 
            route_list = switchModel.Routes.query.filter_by(range_uuid=switch.range_uuid).all()
            # 解除和该交换机连接的路由器
            for router in route_list:
                if router.binding_switchs:
                    subnet_list = router.binding_switchs.split(",")
                    if str(switch.id) in subnet_list:
                        index = subnet_list.index(str(switch.id))
                        subnet_list.pop(index)
                        new_binding_switchs = ",".join(subnet_list)
                        switchModel.Routes.query.filter_by(
                            range_uuid=switch.range_uuid
                        ).update({"binding_switchs": new_binding_switchs})
                        break
            # 删除子网
            port_list = switchModel.Ports.query.filter_by(subnet_id=switch.subnet_id).all()
            for port in port_list:
                if port.ip and port.ip in IPy.IP(switch.cidr):
                    db.session.delete(port)
            db.session.delete(switch)
            db.session.commit()
        except Exception:
            db.session.rollback()
            print(traceback.print_exc())
            abort(400, message="删除交换机失败")
    
    def del_connect_router_database(self, port_id, **kwargs):
        """vpc网络的解绑路由器"""
        try:
            port_info = switchModel.Ports.query.filter_by(
                port_id=port_id, device_owner="router_gw").first()
            router_info = switchModel.Routes.query.filter_by(
                op_route=port_info.device_id, range_uuid=port_info.range_uuid).first()
            switch_db = switchModel.Switchs.query.filter_by(
                range_uuid=port_info.range_uuid, subnet_id=port_info.subnet_id).first()
            subnet_list = router_info.binding_switchs.split(",")
            index = subnet_list.index(str(switch_db.id))
            subnet_list.pop(index)
            binding_switchs = ",".join(subnet_list) if subnet_list else None
            switchModel.Routes.query.filter_by(
                range_uuid=port_info.range_uuid, op_route=router_info.op_route
            ).update({"binding_switchs": binding_switchs})
            db.session.delete(port_info)
            db.session.commit()
        except Exception:
            db.session.rollback()
            print(traceback.print_exc())
            abort(400, message="解绑路由器失败")
            
    def del_connect_vm_database(self, port_id, **kwargs):
        """卸载云主机的网卡"""
        try:
            port_info = switchModel.Ports.query.filter_by(port_id=port_id).first()
            # 删除vm的subnet_id记录
            rangeModel.RangeVm.query.filter_by(vm_uuid=port_info.device_id).update(
                {"subnet_id": None, "v4_fixed_ip": None}
            )
            db.session.delete(port_info)
            db.session.commit()
        except Exception:
            db.session.rollback()
            abort(400, message="卸载云主机网卡失败")
            
    def del_router_database(self, router_uuid, **kwargs):
        """删除路由器数据库"""
        try:
            router = switchModel.Routes.query.filter_by(op_route=router_uuid).first()
            router_tables = switchModel.RouterTable.query.filter_by(
                router_id=router.op_route
            ).all()
            for table in router_tables:
                db.session.delete(table)
            db.session.delete(router)
            db.session.commit()
        except Exception:
            db.session.rollback()
            abort(400, message="删除路由器失败")
    
    def update_active_vm_external_ip_database(self, vipIp, uuid, vm_uuid, **kwargs):
        """更新external_ip"""
        try:
            rangeModel.ActiveRangeVm.query.filter_by(
                new_vm_uuid=vm_uuid
            ).update({"external_ip": vipIp, "eip_uuid": uuid})
            db.session.commit()
        except Exception:
            db.session.rollback()
    
    def update_vm_external_ip_database(self, vipIp, uuid, vm_uuid, **kwargs):
        """更新external_ip"""
        try:
            rangeModel.RangeVm.query.filter_by(
                vm_uuid=vm_uuid
            ).update({"external_ip": vipIp, "eip_uuid": uuid})
            db.session.commit()
        except Exception:
            db.session.rollback()
    
    def del_range_database(self, range_uuid, **kwargs):
        """删除场景"""
        try:
            range_info = rangeModel.Range.query.join(
                rangeModel.RangeLinkModule, rangeModel.RangeLinkModule.range_id == rangeModel.Range.id
            ).filter_by(range_uuid=range_uuid).first()

            if range_info is None:
                abort(400, message="靶场不存在")
            # 清除对应数据库
            db.session.delete(range_info)
            db.session.commit()         
        except Exception:
            print(traceback.print_exc())
            db.session.rollback()
    
    def del_security_group_database(self, security_group_uuid, **kwargs):
        """删除安全组数据库"""
        try:
            security_group_info = rangeModel.SecurityGroup.query.filter_by(security_group_uuid=security_group_uuid).first()
            if security_group_info:
                db.session.delete(security_group_info)
                db.session.commit()
        except Exception:
            db.session.rollback()
            print(traceback.print_exc())
            abort(400, message="删除安全组失败")
    
    def add_stack_template_database(self, uuid, range_uuid, content, stack_name, **kwargs):
        """保存资源栈模板"""
        try:
            stack_tpl = rangeModel.StackTemplate(
                stack_name=stack_name,
                range_uuid=range_uuid,
                stack_uuid=uuid,
                template_content=content,
                is_system=kwargs["is_system"]
            )
            print(uuid, )
            db.session.add(stack_tpl)
            db.session.commit()
        except Exception:
            db.session.rollback()
            abort(400, message="保存资源栈失败")
    
    def add_stack_resource_database(self, uuid, name, stack_uuid, user_id, range_uuid, **kwargs):
        """保存学生开启环境的资源基础数据"""
        try:
            stack_resource_obj = rangeModel.StackResource(
                    resource_stack_uuid=uuid,
                    resource_stack_name=name,
                    range_uuid=range_uuid,
                    user_id=user_id,
                    stack_uuid=stack_uuid
                )
            db.session.add(stack_resource_obj)
            db.session.commit()
        except Exception:
            db.session.rollback()
            abort(400, message="保存数据失败")
    
    # ================== 失败-删除 =======================
    def failed_to_del(self, operate, **kwargs):
        func_type = DELETE_OPERATE_TYPE.get(operate, "")
        if not  func_type:
            return
        method_data = OPERATE_TYPE_DELETE_FUNCTION.get(func_type, {})
        for  method in method_data.get("function", []):
            try:
                if method == "callback_database":
                    self.callback_database(method_data["db_model"], method_data["filter_field"], method_data["on_delete"], method_data.get("update_data", {}), **kwargs)
                else:
                    eval(f"self.{method}")(method_data["db"])
            except Exception:
                print(traceback.print_exc())
    
    def callback_database(self, db_model, filter_field, on_delete, update_data, **kwargs):
        """回调更新数据库"""
        try:
            sqla_str = f"{db_model}.query.filter_by({filter_field}='{kwargs[filter_field]}')"
            if on_delete:
                # 删除
                eval(f"{sqla_str}.delete()")
            else:
                # 更新
                eval(f"{sqla_str}.update({update_data})")
            db.session.commit()
        except Exception:
            db.session.rollback()

    # ================== get-sync ========================
    
    # def get_vm_details(self, vm_uuid, **kwargs):
    #     """获取云主机详情"""
    #     return super().get_vm_details(vm_uuid)
    
    # def get_flavors_details(self, flavor_uuid, **kwargs):
    #     """获取规则"""
    #     return super().get_flavors_details(flavor_uuid)
